home *** CD-ROM | disk | FTP | other *** search
- /*
- * this file contains ALL the logging routines
- */
- #include "passwd.h"
-
- /*
- * these are keywords for log levels
- */
- struct logkey {
- char *word; /* what the user types */
- int wlen; /* how long it is */
- unsigned short level; /* what bit to set */
- } levels[] = {
- { "syntax", 6, LG_SYNTAX, },
- { "use", 3, LG_USE, },
- { "result", 6, LG_RESULT, },
- { "item", 4, LG_ITEM, },
- { "debug", 5, LG_DEBUG, },
- { "system", 6, LG_SYSTEM, },
- { "all", 3, LG_ALL, },
- { CH_NULL, 0, LG_NONE, },
- };
-
- /*
- * each log gets an entry like this
- */
- struct loginfo {
- unsigned short log; /* what is being logged (level) */
- char *loc; /* whee it is going to */
- FILE *locp; /* file pointer if needed */
- unsigned short flags; /* generic flag describing loc */
- } logto[MAXLOGTO];
- static int nlogto = 0; /* number of logs being used */
-
- /*
- * initialize the logging
- */
- initlog()
- {
- beginlog(LG_INIT);
- }
-
- /*
- * load the logging level
- */
- beginlog(line)
- char *line;
- {
- register unsigned short logwhat;/* what is to be logged */
- register int sgn; /* 1 if number is negative */
- register struct logkey *lp; /* walks logging list */
- register int i; /* counter in a for loop */
- char *l1; /* pointer in a for loop */
-
- /*
- * clobber any new line and set up default logging
- */
- if (line[i = strlen(line)-1] == '\n')
- line[i] = '\0';
- logwhat = LG_DEFAULT;
-
- /*
- * skip leading blanks and if nothing, quit
- */
- while(isspace(*line))
- line++;
- if (!*line)
- return;
- /*
- * now just walk the line
- */
- while(*line){
- /*
- * skip leading blanks and commas
- */
- while(*line == ' ' || *line == ',')
- line++;
- /*
- * if at the end of the types, drop out
- */
- if (*line == '\t' || *line == '\0')
- break;
- /*
- * is it negation?
- */
- sgn = 0;
- if (*line == '!'){
- sgn = 1;
- line++;
- }
- /*
- * look for the special case "clear"
- */
- if (strncmp(line, "clear", 5) == 0 && log_end(line[5])){
- if (!sgn)
- log_reset(logwhat, LG_ALL);
- line = &line[5];
- continue;
- }
- /*
- * see if the word matches anything
- */
- for(lp = levels; lp->word != CH_NULL; lp++)
- if (strncmp(line, lp->word, lp->wlen) == 0 &&
- !isalnum(line[lp->wlen])){
- if (sgn)
- log_reset(logwhat, lp->level);
- else
- log_set(logwhat, lp->level);
- line = &line[lp->wlen];
- break;
- }
- /*
- * unknown option
- */
- if (lp->word == CH_NULL){
- while(*line && !isspace(*line) && *line != ',')
- line++;
- }
- }
- /*
- * fake an output if there is none
- */
- if (*line == '\0')
- line = LG_OUTDEF;
- /*
- * now go for the output
- */
- while(isspace(*line))
- line++;
- /*
- * see if it's already used
- */
- for(l1 = &line[1]; isspace(*l1); l1++);
- for(i = 0; i < nlogto; i++){
- if (logto[i].loc[0] != *line)
- continue;
- if (strcmp(&logto[i].loc[1], l1) == 0)
- break;
- }
- /*
- * it is
- */
- if (i != nlogto){
- /*
- * if cleared, close it
- */
- if (logwhat == LG_NONE){
- endlogging(i);
- return;
- }
- /*
- * if now logging LG_USE, say so
- */
- if (log_test(logwhat, LG_USE) &&
- !log_test(logto[i].log, LG_USE)){
- char tbuf[BUFSIZ];
- SPRINTF(tbuf,
- "run by %s on account %s, password file %s, configuration file %s",
- runner, user, pwdfile, pwtest);
- logout(i, tbuf);
- }
- /*
- * change the flags and quit
- */
- logto[i].log = logwhat;
- return;
- }
- /*
- * if you're clearing something not set, you're done!
- */
- if (logwhat == LG_NONE)
- return;
- /*
- * new log
- */
- if (strncmp("stderr", line, 6) == 0){ /* standard error */
- logto[nlogto].locp = stderr;
- logto[nlogto].flags = LG_STDERR;
- line++;
- }
- else if (strncmp("syslog", line, 6) == 0){ /* syslog */
- OPENLOG(progname, LOG_PID, LOG_USER);
- logto[nlogto].locp = stderr;
- logto[nlogto].flags = LG_SYSLOG;
- line++;
- }
- else if (*line == '|'){ /* to a program */
- line++;
- while(isspace(*line))
- line++;
- logto[nlogto].locp = popen(line, "w");
- logto[nlogto].flags = LG_PIPE;
- line[-1] = '|';
- }
- else if (*line == '>'){ /* to a file */
- line++;
- while(isspace(*line))
- line++;
- logto[nlogto].locp = fopen(line, "a");
- logto[nlogto].flags = LG_FILE;
- line[-1] = '>';
- }
- else{ /* ??? */
- LOG2(LG_SYNTAX,
- "bad location to log to on line %d (at \"%s\")",
- linect, line);
- return;
- }
- /*
- * can't open a program or a file
- */
- if (logto[nlogto].locp == FI_NULL){
- LOG2(LG_SYSTEM, "cannot log to \"%s\" on line %d",
- line, linect);
- return;
- }
- /*
- * save where it's going to be logged
- * and what is to be logged
- */
- logto[nlogto].loc = strsave(line-1);
- logto[nlogto].log = logwhat;
-
- /*
- * if logging use,
- * announce who's doing the dirty deed
- */
- if (log_test(logto[nlogto].log, LG_USE)){
- char tbuf[BUFSIZ];
- SPRINTF(tbuf, "run by %s on account %s, password file %s",
- runner, user, pwdfile);
- logout(nlogto, tbuf);
- }
- /*
- * one more item to be logged
- */
- nlogto++;
- }
-
- /*
- * logging function
- */
- logfunc(flag, str)
- unsigned int flag; /* what this is */
- char *str; /* log message */
- {
- register int i; /* counter in a for loop */
-
- /*
- * log the message in all appropriate logs
- */
- for(i = 0; i < nlogto; i++)
- if (log_test(logto[i].log, flag))
- logout(i, str);
- }
-
- /*
- * does the actual logging for one log
- */
- logout(logno, str)
- int logno; /* log number */
- char *str; /* mesage */
- {
- /*
- * syslog is treated special if SYSLOG is defined
- * the rest just go out
- */
- #ifdef SYSLOG
- if (logto[logno].flags == LG_SYSLOG)
- syslog(LOG_INFO, str);
- else
- #endif
- FPRINTF(logto[logno].locp, "%s(%5d): %s\n",
- progname, getpid(), str);
- }
-
- /*
- * close a log
- */
- endlogging(logno)
- int logno; /* log number */
- {
- /*
- * closing the specific log depends on what it is
- */
- switch(logto[logno].flags){
- case LG_STDERR: /* NEVER close stderr! */
- break;
- #ifdef SYSLOG
- case LG_SYSLOG: /* break connection on syslog() */
- closelog();
- break;
- #endif
- case LG_PIPE: /* close pipe for program */
- (void) pclose(logto[logno].locp);
- break;
- case LG_FILE: /* close file for file */
- (void) fclose(logto[logno].locp);
- break;
- }
- /*
- * now delete the log entry by moving the final
- * one over it (if there is another log)
- */
- if (nlogto--> 1){
- logto[logno].log = logto[nlogto].log;
- logto[logno].loc = logto[nlogto].loc;
- logto[logno].locp = logto[nlogto].locp;
- logto[logno].flags = logto[nlogto].flags;
- }
- }
-